﻿using JSONDB.helpers;
using MongoDB.Driver;
using Newtonsoft.Json.Linq;
using NLog;
using OPCService.Job;
using OPCService.Model;
using OPCService.Service;
using OPCService.Utils;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SQLite;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows.Forms;
using JSONItem = JSONDB.Item; //别名
using OpcItem = OPCService.Model.Item;

namespace OPCService
{
    public partial class ACCS : Form
    {
        private static readonly Logger logger = NLog.LogManager.GetCurrentClassLogger();
        private static string jsonconfig = AppDomain.CurrentDomain.BaseDirectory + @ConfigHelper.ReadConfig("jsondb");
        private static readonly String colName = ConfigHelper.ReadConfig("colname");
        private static readonly String accs = ConfigHelper.ReadConfig("accs");
        private static readonly String sqliteName = ConfigHelper.ReadConfig("sqliteName");
        private static readonly int preditPeriod = int.Parse(ConfigHelper.ReadConfig("preditPeriod"));
        private static readonly int computerPeriod = int.Parse(ConfigHelper.ReadConfig("computerPeriod"));
        private static readonly String opc500name = ConfigHelper.ReadConfig("Opc500DataCollection");
        private static readonly String opc800name = ConfigHelper.ReadConfig("Opc800DataCollection");
        private static Timer dataTimer;    //获取数据更新界面
        private static Timer predictTimer; //模型预测计时器
        private static Timer grateLine1BackwardTimer;
        private static Timer grateLine2BackwardTimer;
        private static Timer grateLine3BackwardTimer;
        private static Timer grateLine4BackwardTimer;
        private static Timer grateLine1ForwardTimer;
        private static Timer grateLine2ForwardTimer;
        private static Timer grateLine3ForwardTimer;
        private static Timer grateLine4ForwardTimer;
        private static Timer pusher1Timer;
        private static Timer pusher2Timer;
        private static Timer pusher3Timer;
        private static Timer pusher4Timer;
        private static int grateLine1BackwardTotalTime = 0; //累计时间
        private static int grateLine2BackwardTotalTime = 0;
        private static int grateLine3BackwardTotalTime = 0;
        private static int grateLine4BackwardTotalTime = 0;
        private static int grateLine1ForwardTotalTime = 0;
        private static int grateLine2ForwardTotalTime = 0;
        private static int grateLine3ForwardTotalTime = 0;
        private static int grateLine4ForwardTotalTime = 0;
        private static int pusher1TotalTime = 0;
        private static int pusher2TotalTime = 0;
        private static int pusher3TotalTime = 0;
        private static int pusher4TotalTime = 0;
        private static bool isRunning = false;

        private static MongoDbHelper mongoDbHelper = new MongoDbHelper();
        private static JsonDBHelper jsonDBHelper;
        private InputPvData input_PV_data = new InputPvData();//创建对象
        private Setpoints setpoints = new Setpoints();         //创建对象
        private Status status = new Status();
        private ControlAction control_action = new ControlAction();
        private StabilityDiagnosis stability_diagnosis = new StabilityDiagnosis();

        public ACCS()
        {
            InitializeComponent();
            // 设置窗体启动位置在屏幕中心
            this.StartPosition = FormStartPosition.CenterScreen;
            // 设置窗体图标（需要确保图标文件已添加到项目资源）
            this.Icon = new Icon("Resource/accs32.ico");
            this.FormClosed += MainForm_FormClosed;
            this.FormClosing += MainForm_FormClosing;

            // 初始化计时器
            TimerInit();
            LoadSettings();
        }

        //主窗体中注册退出事件
        private async void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            try
            {
                Console.WriteLine("**************");
                await Program.OnApplicationExitAsync();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"程序退出时出错: {ex.Message}");
            }
        }

        //主窗体中关闭确认
        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            // 检查关闭原因是否为用户操作（点击关闭按钮）
            if (e.CloseReason == CloseReason.UserClosing)
            {
                // 弹出确认对话框
                DialogResult result = MessageBox.Show(
                    "您确定要关闭此窗口吗？",
                    "确认关闭",
                    MessageBoxButtons.YesNo,
                    MessageBoxIcon.Question);

                // 如果用户点击“否”，取消关闭操作
                if (result == DialogResult.No)
                {
                    e.Cancel = true;
                }
            }
        }

        //加载系统设置数据
        private void LoadSettings()
        {
            // 示例：读取并显示设置
            int steamFlowLower = Properties.Settings.Default.steamFlowLower;
            int steamFlowUpper = Properties.Settings.Default.steamFlowUpper;
            int steamTemperatureLower = Properties.Settings.Default.steamTemperatureLower;
            int steamTemperatureUpper = Properties.Settings.Default.steamTemperatureUpper;
            int incineratorTemperatureLower = Properties.Settings.Default.incineratorTemperatureLower;
            int incineratorTemperatureUpper = Properties.Settings.Default.incineratorTemperatureUpper;
            int incineratorOxygenLower = Properties.Settings.Default.incineratorOxygenLower;
            int incineratorOxygenUpper = Properties.Settings.Default.incineratorOxygenUpper;
            int incineratorPressureLower = Properties.Settings.Default.incineratorPressureLower;
            int incineratorPressureUpper = Properties.Settings.Default.incineratorPressureUpper;
            int validDataRange = Properties.Settings.Default.validDataRange;
            int validPeriodRange = Properties.Settings.Default.validPeriodRange;
            int steamFlowSettingVal = Properties.Settings.Default.steamFlowSettingVal;
            int qibaoMax = Properties.Settings.Default.qibaoMax;
            int qibaoLower = Properties.Settings.Default.qibaoLower;
            int qibaoUpper = Properties.Settings.Default.qibaoUpper;
            lblStramFlowRange.Text = steamFlowLower + "~" + steamFlowUpper;
            lblStramTemperatureRange.Text = steamTemperatureLower + "~" + steamTemperatureUpper;
            lblBoilerTemperatureRange.Text = incineratorTemperatureLower + "~" + incineratorTemperatureUpper;
            lblBoilerOxygenRange.Text = incineratorOxygenLower + "~" + incineratorOxygenUpper;
            lblBoilerPressureRange.Text = incineratorPressureLower + "~" + incineratorPressureUpper;
            lblLpPeriod.Text = "炉排周期（" + validPeriodRange + "秒内）";
            lblDataStatus.Text = "数据状态（" + validDataRange + "秒内）";
            lblSteamFlowSettingVal.Text = steamFlowSettingVal + "t/h";
            waterLevelQb.MaxValue = qibaoMax;
            waterLevelQb.LowAlarm = qibaoLower;
            waterLevelQb.HighAlarm = qibaoUpper;
        }

        //计时器初始化，获取当前时间和运行参数
        private void TimerInit()
        {
            dataTimer = new Timer { Interval = 1000 };
            dataTimer.Tick += DataTimer_Tick;

            predictTimer = new Timer { Interval = preditPeriod };
            predictTimer.Tick +=PredictTimer_Tick;

            //预测初始值默认为0
            control_action.grate_line1_backward_period = 0;
            control_action.grate_line2_backward_period = 0;
            control_action.grate_line3_backward_period = 0;
            control_action.grate_line4_backward_period = 0;
            control_action.grate_line1_forward_period = 0;
            control_action.grate_line2_forward_period = 0;
            control_action.grate_line3_forward_period = 0;
            control_action.grate_line4_forward_period = 0;

            grateLine1BackwardTimer = new Timer { Interval = computerPeriod };
            grateLine1BackwardTimer.Tick += GrateLine1BackwardTimer_Tick;
            
            grateLine2BackwardTimer = new Timer { Interval = computerPeriod };
            grateLine2BackwardTimer.Tick += GrateLine2BackwardTimer_Tick;

            grateLine3BackwardTimer = new Timer { Interval = computerPeriod };
            grateLine3BackwardTimer.Tick += GrateLine3BackwardTimer_Tick;

            grateLine4BackwardTimer = new Timer { Interval = computerPeriod };
            grateLine4BackwardTimer.Tick += GrateLine4BackwardTimer_Tick;

            grateLine1ForwardTimer = new Timer { Interval = computerPeriod };
            grateLine1ForwardTimer.Tick += GrateLine1ForwardTimer_Tick;

            grateLine2ForwardTimer = new Timer { Interval = computerPeriod };
            grateLine2ForwardTimer.Tick += GrateLine2ForwardTimer_Tick;
            
            grateLine3ForwardTimer = new Timer { Interval = computerPeriod };
            grateLine3ForwardTimer.Tick += GrateLine3ForwardTimer_Tick;
            
            grateLine4ForwardTimer = new Timer { Interval = computerPeriod };
            grateLine4ForwardTimer.Tick += GrateLine4ForwardTimer_Tick;

            pusher1Timer = new Timer { Interval = computerPeriod };
            pusher1Timer.Tick += Pusher1Timer_Tick;

            pusher2Timer = new Timer { Interval = computerPeriod };
            pusher2Timer.Tick += Pusher2Timer_Tick;

            pusher3Timer = new Timer { Interval = computerPeriod };
            pusher3Timer.Tick += Pusher3Timer_Tick;

            pusher4Timer = new Timer { Interval = computerPeriod };
            pusher4Timer.Tick += Pusher4Timer_Tick;
        }

        //周期性调用模型进行预测
        private void PredictTimer_Tick(object sender, EventArgs e)
        {
            //模型预测, 预测请求参数在每秒运行的DataTimer中请求获取
            Task.Run(async () =>
            {
                try
                {
                    if (isRunning)
                    {
                        await Predit();
                    }
                }
                catch (Exception ex)
                { }
            });
        }

        //计时器事件 一号炉排逆推周期回调
        private void GrateLine1BackwardTimer_Tick(object sender, EventArgs e)
        {
            //累计时间
            grateLine1BackwardTotalTime = grateLine1BackwardTotalTime + computerPeriod;
            ntCurrPeriod1.Text = (grateLine1BackwardTotalTime/1000).ToString() + " 秒";
            Task.Run(async () =>
            {
                try
                {
                    logger.Info(control_action.grate_line1_backward_period + "<=============Line1BackwardTimer_Tick===========" + grateLine1BackwardTotalTime / 1000);
                    //AI接入，炉排控制结束前重置累计时间
                    if (control_action.grate_line1_backward_period < grateLine1BackwardTotalTime / 1000)
                    {
                        logger.Info("=============AI grateLine1BackwardTimer reset===========");
                        grateLine1BackwardTotalTime = 0;//从新计时

                        //炉排控制
                        GrateLineService Line1Backward = new GrateLineService("炉排1号逆推进到位信号", "炉排1号逆推退到位信号", "炉排1号逆推前进指令", "炉排1号逆推后退指令");
                    }
                }
                catch (Exception ex)
                {}
            });
        }

        private void GrateLine2BackwardTimer_Tick(object sender, EventArgs e)
        {
            //累计时间
            grateLine2BackwardTotalTime = grateLine2BackwardTotalTime + computerPeriod;
            ntCurrPeriod2.Text = (grateLine2BackwardTotalTime / 1000).ToString() + " 秒";
            Task.Run(async () =>
            {
                try
                {
                    if (control_action.grate_line2_backward_period < grateLine2BackwardTotalTime / 1000)
                    {
                        grateLine2BackwardTotalTime = 0;

                        //炉排控制
                        GrateLineService Line2Backward = new GrateLineService("炉排2号逆推进到位信号", "炉排2号逆推退到位信号", "炉排2号逆推前进指令", "炉排2号逆推后退指令");
                    }
                }
                catch (Exception ex)
                {}
            });
        }

        private void GrateLine3BackwardTimer_Tick(object sender, EventArgs e)
        {
            //累计时间
            grateLine3BackwardTotalTime = grateLine3BackwardTotalTime + computerPeriod;
            ntCurrPeriod3.Text = (grateLine3BackwardTotalTime / 1000).ToString() + " 秒";
            Task.Run(async () =>
            {
                try
                {
                    if (control_action.grate_line3_backward_period < grateLine3BackwardTotalTime / 1000)
                    {
                        grateLine3BackwardTotalTime = 0;

                        //炉排控制
                        GrateLineService Line3Backward = new GrateLineService("炉排3号逆推进到位信号", "炉排3号逆推退到位信号", "炉排3号逆推前进指令", "炉排3号逆推后退指令");
                    }
                }
                catch (Exception ex)
                {}
            });
        }

        private void GrateLine4BackwardTimer_Tick(object sender, EventArgs e)
        {
            //累计时间
            grateLine4BackwardTotalTime = grateLine4BackwardTotalTime + computerPeriod;
            ntCurrPeriod4.Text = (grateLine4BackwardTotalTime / 1000).ToString() + " 秒";
            Task.Run(async () =>
            {
                try
                {
                    if (control_action.grate_line4_backward_period < grateLine4BackwardTotalTime / 1000)
                    {
                        grateLine4BackwardTotalTime = 0;

                        //炉排控制
                        GrateLineService Line4Backward = new GrateLineService("炉排4号逆推进到位信号", "炉排4号逆推退到位信号", "炉排4号逆推前进指令", "炉排4号逆推后退指令");
                    }
                }
                catch (Exception ex)
                {}
            });
        }

        private void GrateLine1ForwardTimer_Tick(object sender, EventArgs e)
        {
            //累计时间
            grateLine1ForwardTotalTime = grateLine1ForwardTotalTime + computerPeriod;
            stCurrPeriod1.Text = (grateLine1ForwardTotalTime / 1000).ToString() + " 秒";
            Task.Run(async () =>
            {
                try
                {
                    if (control_action.grate_line1_forward_period < grateLine1ForwardTotalTime/1000)
                    {
                        grateLine1ForwardTotalTime = 0;

                        //炉排控制
                        GrateLineService Line1Forward = new GrateLineService("炉排1号顺推进到位信号", "炉排1号顺推退到位信号", "炉排1号顺推前进指令", "炉排1号顺推后退指令");
                    }
                }
                catch (Exception ex)
                {}
            });
        }

        private void GrateLine2ForwardTimer_Tick(object sender, EventArgs e)
        {
            //累计时间
            grateLine2ForwardTotalTime = grateLine2ForwardTotalTime + computerPeriod;
            stCurrPeriod2.Text = (grateLine2ForwardTotalTime / 1000).ToString() + " 秒";
            Task.Run(async () =>
            {
                try
                {
                    if (control_action.grate_line2_forward_period < grateLine2ForwardTotalTime/1000)
                    {
                        grateLine2ForwardTotalTime = 0;

                        //炉排控制
                        GrateLineService Line2Forward = new GrateLineService("炉排2号顺推进到位信号", "炉排2号顺推退到位信号", "炉排2号顺推前进指令", "炉排2号顺推后退指令");
                    }
                }
                catch (Exception ex)
                {}
            });
        }

        private void GrateLine3ForwardTimer_Tick(object sender, EventArgs e)
        {
            //累计时间
            grateLine3ForwardTotalTime = grateLine3ForwardTotalTime + computerPeriod;
            stCurrPeriod3.Text = (grateLine3ForwardTotalTime / 1000).ToString() + " 秒";
            Task.Run(async () =>
            {
                try
                {
                    if (control_action.grate_line3_forward_period < grateLine3ForwardTotalTime/1000)
                    {
                        grateLine3ForwardTotalTime = 0;

                        //炉排控制
                        GrateLineService Line3Forward = new GrateLineService("炉排3号顺推进到位信号", "炉排3号顺推退到位信号", "炉排3号顺推前进指令", "炉排3号顺推后退指令");
                    }
                }
                catch (Exception ex)
                {}
            });
        }

        private void GrateLine4ForwardTimer_Tick(object sender, EventArgs e)
        {
            //累计时间
            grateLine4ForwardTotalTime = grateLine4ForwardTotalTime + computerPeriod;
            stCurrPeriod4.Text = (grateLine4ForwardTotalTime / 1000).ToString() + " 秒";
            Task.Run(async () =>
            {
                try
                {
                    if (control_action.grate_line4_forward_period < grateLine4ForwardTotalTime/1000)
                    {
                        grateLine4ForwardTotalTime = 0;

                        //炉排控制
                        GrateLineService Line4Forward = new GrateLineService("炉排4号顺推进到位信号", "炉排4号顺推退到位信号", "炉排4号顺推前进指令", "炉排4号顺推后退指令");
                    }
                }
                catch (Exception ex)
                {}
            });
        }

        private void Pusher1Timer_Tick(object sender, EventArgs e)
        {
            //累计时间
            pusher1TotalTime = pusher1TotalTime + computerPeriod;
            lblPusher1CurrPeriod.Text = (pusher1TotalTime / 1000).ToString() + " 秒";
            Task.Run(async () =>
            {
                try
                {
                    if (control_action.pusher1_period < pusher1TotalTime / 1000)
                    {
                        pusher1TotalTime = 0;

                        //推料器控制
                        bool cbAotoWrite = Properties.Settings.Default.cbAotoWrite;
                        if (cbAotoWrite)
                        {
                            int total;
                            //List<JSONItem> items = jsonDBHelper.GetItems(opc500name, 200, 1, out total);
                            //foreach (JSONItem item in items)
                            //{
                            //    if (item.name.Equals("炉排1号推料器行程"))
                            //    {
                            //        //await Opc500DataCollection.WriteData(item.value, control_action.pusher1_period);
                            //        break;
                            //    }
                            //}
                        }
                    }
                }
                catch (Exception ex)
                {

                }
            });
        }

        private void Pusher2Timer_Tick(object sender, EventArgs e)
        {
            //累计时间
            pusher2TotalTime = pusher2TotalTime + computerPeriod;
            lblPusher2CurrPeriod.Text = (pusher2TotalTime / 1000).ToString() + " 秒";
            Task.Run(async () =>
            {
                try
                {
                    if (control_action.pusher2_period < pusher2TotalTime / 1000)
                    {
                        pusher2TotalTime = 0;

                        //推料器控制
                        bool cbAotoWrite = Properties.Settings.Default.cbAotoWrite;
                        if (cbAotoWrite)
                        {
                            int total;
                            //List<JSONItem> items = jsonDBHelper.GetItems(opc500name, 200, 1, out total);
                            //foreach (JSONItem item in items)
                            //{
                            //    if (item.name.Equals("炉排2号推料器行程"))
                            //    {
                            //        //await Opc500DataCollection.WriteData(item.value, control_action.pusher2_period);
                            //        break;
                            //    }
                            //}
                        }

                    }
                }
                catch (Exception ex)
                { }
            });
        }

        private void Pusher3Timer_Tick(object sender, EventArgs e)
        {
            //累计时间
            pusher3TotalTime = pusher3TotalTime + computerPeriod;
            lblPusher3CurrPeriod.Text = (pusher3TotalTime / 1000).ToString() + " 秒";
            Task.Run(async () =>
            {
                try
                {
                    if (control_action.pusher3_period < pusher3TotalTime / 1000)
                    {
                        pusher3TotalTime = 0;

                        //推料器控制
                        bool cbAotoWrite = Properties.Settings.Default.cbAotoWrite;
                        if (cbAotoWrite)
                        {
                            int total;
                            //List<JSONItem> items = jsonDBHelper.GetItems(opc500name, 200, 1, out total);
                            //foreach (JSONItem item in items)
                            //{
                            //    if (item.name.Equals("炉排3号推料器行程"))
                            //    {
                            //        //await Opc500DataCollection.WriteData(item.value, control_action.pusher3_period);
                            //        break;
                            //    }
                            //}
                        }

                    }
                }
                catch (Exception ex)
                { }
            });
        }

        private void Pusher4Timer_Tick(object sender, EventArgs e)
        {
            //累计时间
            pusher4TotalTime = pusher4TotalTime + computerPeriod;
            lblPusher4CurrPeriod.Text = (pusher4TotalTime / 1000).ToString() + " 秒";
            Task.Run(async () =>
            {
                try
                {
                    if (control_action.pusher4_period < pusher4TotalTime / 1000)
                    {
                        pusher4TotalTime = 0;

                        //推料器控制
                        bool cbAotoWrite = Properties.Settings.Default.cbAotoWrite;
                        if (cbAotoWrite)
                        {
                            int total;
                            //List<JSONItem> items = jsonDBHelper.GetItems(opc500name, 200, 1, out total);
                            //foreach (JSONItem item in items)
                            //{
                            //    if (item.name.Equals("炉排4号推料器行程"))
                            //    {
                            //        //await Opc500DataCollection.WriteData(item.value, control_action.pusher4_period);
                            //        break;
                            //    }
                            //}
                        }
                    }
                }
                catch (Exception ex)
                { }
            });
        }

        //模型预测
        private async Task Predit()
        {
            logger.Info("<===========predict func===========>");
            //获取运行数据
            await GetRunningData();   
            //预测请求参数
            await GetPredictParams();

            string path = "ai/accs";
            if (!periodStatus.IsOn)
            {
                logger.Info("<===========炉排周期数据有效时间不满足===========>");
                path = "ai/accs_init";//启动模型接口
            }
            if (!dataStatus.IsOn)
            {
                logger.Info("<===========历史数据有效时间不满足===========>");
                return;
            }

            var requestParams = new RequestModel
            {
                input_PV_data = input_PV_data,
                setpoints = setpoints
            };
            logger.Info("<===========predict request===========>");
            string baseUrl = accs;
            HttpService httpService = new HttpService(baseUrl);
            string json1 = JsonSerializer.Serialize(requestParams, new JsonSerializerOptions { WriteIndented = true, Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping });
            logger.Info("<===========request params=============>" + json1);
            // 发送 POST 请求
            var response = await httpService.PostAsync<ResponseModel>(path, requestParams);
            ControlAction rtn_control_action = response.control_action;

            //预测值为0时不赋值，保持原有值
            if (rtn_control_action.grate_line1_backward_period != 0)
            {
                control_action.grate_line1_backward_period = rtn_control_action.grate_line1_backward_period;
            }
            if (rtn_control_action.grate_line2_backward_period != 0)
            {
                control_action.grate_line2_backward_period = rtn_control_action.grate_line2_backward_period;
            }
            if (rtn_control_action.grate_line3_backward_period != 0)
            {
                control_action.grate_line3_backward_period = rtn_control_action.grate_line3_backward_period;
            }
            if (rtn_control_action.grate_line4_backward_period != 0)
            {
                control_action.grate_line4_backward_period = rtn_control_action.grate_line4_backward_period;
            }
            if (rtn_control_action.grate_line1_forward_period != 0)
            {
                control_action.grate_line1_forward_period = rtn_control_action.grate_line1_forward_period;
            }
            if (rtn_control_action.grate_line2_forward_period != 0)
            {
                control_action.grate_line2_forward_period = rtn_control_action.grate_line2_forward_period;
            }
            if (rtn_control_action.grate_line3_forward_period != 0)
            {
                control_action.grate_line3_forward_period = rtn_control_action.grate_line3_forward_period;
            }
            if (rtn_control_action.grate_line4_forward_period != 0)
            {
                control_action.grate_line4_forward_period = rtn_control_action.grate_line4_forward_period;
            }
            control_action.wind1 = rtn_control_action.wind1;
            control_action.wind2 = rtn_control_action.wind2;
            control_action.pusher1_period = rtn_control_action.pusher1_period;
            control_action.pusher2_period = rtn_control_action.pusher2_period;
            control_action.pusher3_period = rtn_control_action.pusher3_period;
            control_action.pusher4_period = rtn_control_action.pusher4_period;

            stability_diagnosis = response.stability_diagnosis;
            status = response.status;

            string json2 = JsonSerializer.Serialize(response, new JsonSerializerOptions { WriteIndented = true, Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping });
            logger.Info("<===========predit response===========>" + json2);
            if (status!= null && status.requires_ai_intervention && control_action != null)
            {
                bool cbAotoWrite = Properties.Settings.Default.cbAotoWrite;
                //AI 写入 OPC
                int total;
                List<JSONItem> items = jsonDBHelper.GetItems(opc800name, 200, 1, out total);
                foreach (JSONItem item in items)
                {
                    if (item.name.Equals("一次风机给定"))
                    {
                        if (cbAotoWrite)
                        {
                            await Opc800DataCollection.WriteData(item.value, control_action.wind1);
                        }
                    }
                    if (item.name.Equals("二次风机给定"))
                    {
                        if (cbAotoWrite)
                        {
                            await Opc800DataCollection.WriteData(item.value, control_action.wind1);
                        }
                    }
                }
            }

            //模型预测，更新界面，周期预测数据
            this.Invoke((Action)(() =>
            {
                if (control_action != null && control_action.grate_line1_backward_period > 0)
                {
                    lbl_backward_predict1.Text = (int)control_action.grate_line1_backward_period + " 秒";
                }
                if (control_action != null && control_action.grate_line2_backward_period > 0)
                {
                    lbl_backward_predict2.Text = (int)control_action.grate_line2_backward_period + " 秒";
                }
                if (control_action != null && control_action.grate_line3_backward_period > 0)
                {
                    lbl_backward_predict3.Text = (int)control_action.grate_line3_backward_period + " 秒";
                }
                if (control_action != null && control_action.grate_line4_backward_period > 0)
                {
                    lbl_backward_predict4.Text = (int)control_action.grate_line4_backward_period + " 秒";
                }
                if (control_action != null && control_action.grate_line1_forward_period > 0)
                {
                    lbl_forward_predict1.Text = (int)control_action.grate_line1_forward_period + " 秒";
                }
                if (control_action != null && control_action.grate_line2_forward_period > 0)
                {
                    lbl_forward_predict2.Text = (int)control_action.grate_line2_forward_period + " 秒";
                }
                if (control_action != null && control_action.grate_line3_forward_period > 0)
                {
                    lbl_forward_predict3.Text = (int)control_action.grate_line3_forward_period + " 秒";
                }
                if (control_action != null && control_action.grate_line4_forward_period > 0)
                {
                    lbl_forward_predict4.Text = (int)control_action.grate_line4_forward_period + " 秒";
                }
                if (control_action != null && control_action.wind1 > 0)
                {
                    lblWindPredit1.Text = (int)control_action.wind1 + " Hz";
                }
                if (control_action != null && control_action.wind2 > 0)
                {
                    lblWindPredit2.Text = (int)control_action.wind2 + " Hz";
                }
                if (control_action != null && control_action.pusher1_period > 0)
                {
                    lblTlqPredit1.Text = (int)control_action.pusher1_period + " 秒";
                }
                if (control_action != null && control_action.pusher2_period > 0)
                {
                    lblTlqPredit2.Text = (int)control_action.pusher2_period + " 秒";
                }
                if (control_action != null && control_action.pusher3_period > 0)
                {
                    lblTlqPredit3.Text = (int)control_action.pusher3_period + " 秒";
                }
                if (control_action != null && control_action.pusher4_period > 0)
                {
                    lblTlqPredit4.Text = (int)control_action.pusher4_period + " 秒";
                }
                if (status.requires_manual_intervention)
                {
                    ToastMessage.Show(this, status.manual_alert_messages[0], ToastType.Error);
                    string status_string = "";
                    foreach(string text in status.manual_alert_messages)
                    {
                        if(status_string != "")
                        {
                            status_string += "，" + text;
                        }
                        else
                        {
                            status_string = text;
                        }
                    }
                    tsslStatus.Text = status_string;
                    tsslStatus.ForeColor = Color.Red;
                    modelStatus.IsOn = false;
                }
                else
                {
                    tsslStatus.Text = "AI正常运行中";
                    tsslStatus.ForeColor = Color.LimeGreen;
                    modelStatus.IsOn = true;
                }
            }));
        }

        //设置历史值对象属性值
        private void SetPvDataProvertyValue(string propertyName, List<double> valueList)
        {
            // 通过反射获取属性信息
            PropertyInfo property = input_PV_data.GetType().GetProperty(propertyName);
            if (property != null && property.CanWrite)
            {
                // 动态赋值
                double[] propertyValue = valueList.ToArray();
                property.SetValue(input_PV_data, Convert.ChangeType(propertyValue, property.PropertyType));
                Console.WriteLine($"=================设置成功: {propertyName}");
            }
        }

        //设置区间值对象属性值
        private void SetPointObjectProvertyValue(string propertyName, List<double> valueList)
        {
            // 通过反射获取属性信息
            PropertyInfo property = setpoints.GetType().GetProperty(propertyName);
            if (property != null && property.CanWrite)
            {
                // 动态赋值
                double[] propertyValue = valueList.ToArray();
                property.SetValue(setpoints, Convert.ChangeType(propertyValue, property.PropertyType));
                Console.WriteLine($"=================设置成功: {propertyName}");
            }
        }

        //每秒获取运行数据
        private void DataTimer_Tick(object sender, EventArgs e)
        {
            tsSystem.Text = "系统时间：" + DateTime.Now + "     ";
            Task.Run(async () =>
            {
                try
                {
                    await GetRunningData();      //获取运行数据
                    await checkOpcStatus();      //检测OPC状态
                }
                catch (Exception ex)
                {}
            });
        }

        //获取界面运行数据
        private async Task GetRunningData()
        {
            //logger.Info("=============GetRunningData===========");
            bool currentSteamFlowStatus = true;
            bool currentSteamTempStatus = true;
            bool currentBoilerTempStatus = true;
            bool currentBoilerOxygenStatus = true;
            bool currentBoilerPressureStatus = true;
            int steamFlowLower = Properties.Settings.Default.steamFlowLower;
            int steamFlowUpper = Properties.Settings.Default.steamFlowUpper;
            int steamTemperatureLower = Properties.Settings.Default.steamTemperatureLower;
            int steamTemperatureUpper = Properties.Settings.Default.steamTemperatureUpper;
            int incineratorTemperatureLower = Properties.Settings.Default.incineratorTemperatureLower;
            int incineratorTemperatureUpper = Properties.Settings.Default.incineratorTemperatureUpper;
            int incineratorOxygenLower = Properties.Settings.Default.incineratorOxygenLower;
            int incineratorOxygenUpper = Properties.Settings.Default.incineratorOxygenUpper;
            int incineratorPressureLower = Properties.Settings.Default.incineratorPressureLower;
            int incineratorPressureUpper = Properties.Settings.Default.incineratorPressureUpper;
            string[] tagNames = { "温度上左", "温度上中", "温度上右", "温度中左", "温度中中", "温度中右", "温度下左", "温度下中", "温度下右", "蒸汽流量", "一次风机给定", "一次风机反馈", "二次风机给定", "二次风机反馈", 
                "炉排1号推料器行程", "炉排2号推料器行程", "炉排3号推料器行程", "炉排4号推料器行程", "推料器1号退到位信号", "推料器2号退到位信号", "推料器3号退到位信号", "推料器4号退到位信号", "推料器1号进到位信号", "推料器2号进到位信号", 
                "推料器3号进到位信号", "推料器4号进到位信号", "炉排1号逆推进到位信号", "炉排2号逆推进到位信号", "炉排3号逆推进到位信号", "炉排4号逆推进到位信号", "炉排1号逆推退到位信号", "炉排2号逆推退到位信号", "炉排3号逆推退到位信号", "炉排4号逆推退到位信号",
                "炉排1号顺推进到位信号", "炉排2号顺推进到位信号", "炉排3号顺推进到位信号", "炉排4号顺推进到位信号", "炉排1号顺推退到位信号", "炉排2号顺推退到位信号", "炉排3号顺推退到位信号", "炉排4号顺推退到位信号",
                "含氧量左", "含氧量右", "过热器汇汽集箱温度A", "空气预热器出口风温", "空气预热器一级加热出口风温", "第一通道上部负压左", "第一通道上部负压右", "炉排1号逆推输出", "炉排2号逆推输出", "炉排3号逆推输出", "炉排4号逆推输出",
                "炉排1号顺推输出", "炉排2号顺推输出", "炉排3号顺推输出", "炉排4号顺推输出", "汽包水位"
            };

            //1、获取请求mongodb中历史数据作为参数值
            List<JSONItem> items = jsonDBHelper.GetItems();
            foreach (JSONItem item in items)
            {
                //从MongoDB获取历史数据
                foreach (string propertyName in tagNames)
                {
                    if (propertyName.Equals(item.name))
                    {
                        // 创建构建器
                        var builder = Builders<OpcItem>.Filter;

                        // 构建排序方式：按 datetime 倒序
                        var sort = Builders<OpcItem>.Sort.Descending(x => x.datetime);

                        FilterDefinition<OpcItem> filter = builder.Eq("tag_name", item.value);
                        List<OpcItem> datalist = mongoDbHelper.findLimit<OpcItem>(colName, filter, sort, 3);
                        if (datalist.Count > 0)
                        {
                            foreach (OpcItem data in datalist)
                            {
                                //每秒获取的运行数据
                                this.Invoke((Action)(() =>
                                {
                                    if (propertyName.Equals("温度上左"))
                                    {
                                        lblTopLeftTemp.Text = (int)data.value + " ℃";
                                        currentBoilerTempStatus = currentBoilerTempStatus && data.value >= incineratorTemperatureLower && data.value <= incineratorTemperatureUpper;
                                    }
                                    else if (propertyName.Equals("温度上中"))
                                    {
                                        lblTopMiddleTemp.Text = (int)data.value + " ℃";
                                        currentBoilerTempStatus = currentBoilerTempStatus && data.value >= incineratorTemperatureLower && data.value <= incineratorTemperatureUpper;
                                    }
                                    else if (propertyName.Equals("温度上右"))
                                    {
                                        lblTopRightTemp.Text = (int)data.value + " ℃";
                                        currentBoilerTempStatus = currentBoilerTempStatus && data.value >= incineratorTemperatureLower && data.value <= incineratorTemperatureUpper;
                                    }
                                    else if (propertyName.Equals("温度中左"))
                                    {
                                        lblMiddleLeftTemp.Text = (int)data.value + " ℃";
                                        currentBoilerTempStatus = currentBoilerTempStatus && data.value >= incineratorTemperatureLower && data.value <= incineratorTemperatureUpper;
                                    }
                                    else if (propertyName.Equals("温度中中"))
                                    {
                                        lblMiddleMiddleTemp.Text = (int)data.value + " ℃";
                                        currentBoilerTempStatus = currentBoilerTempStatus && data.value >= incineratorTemperatureLower && data.value <= incineratorTemperatureUpper;
                                    }
                                    else if (propertyName.Equals("温度中右"))
                                    {
                                        lblMiddleRightTemp.Text = (int)data.value + " ℃";
                                        currentBoilerTempStatus = currentBoilerTempStatus && data.value >= incineratorTemperatureLower && data.value <= incineratorTemperatureUpper;
                                    }
                                    else if (propertyName.Equals("温度下左"))
                                    {
                                        lblBottomLeftTemp.Text = (int)data.value + " ℃";
                                        currentBoilerTempStatus = currentBoilerTempStatus && data.value >= incineratorTemperatureLower && data.value <= incineratorTemperatureUpper;
                                    }
                                    else if (propertyName.Equals("温度下中"))
                                    {
                                        lblBottomMiddleTemp.Text = (int)data.value + " ℃";
                                        currentBoilerTempStatus = currentBoilerTempStatus && data.value >= incineratorTemperatureLower && data.value <= incineratorTemperatureUpper;
                                    }
                                    else if (propertyName.Equals("温度下右"))
                                    {
                                        lblBottomRightTemp.Text = (int)data.value + " ℃";
                                        currentBoilerTempStatus = currentBoilerTempStatus && data.value >= incineratorTemperatureLower && data.value <= incineratorTemperatureUpper;
                                    }
                                    else if (propertyName.Equals("蒸汽流量"))
                                    {
                                        lblSteamFlow.Text = (int)data.value + " t/h";
                                        currentSteamFlowStatus = data.value >= steamFlowLower && data.value <= steamFlowUpper;
                                    }
                                    else if (propertyName.Equals("炉排1号推料器行程"))
                                    {
                                        tlqXc1.Value = ((int)(data.value)) * 100 / 850;
                                    }
                                    else if (propertyName.Equals("炉排2号推料器行程"))
                                    {
                                        tlqXc2.Value = ((int)(data.value)) * 100 / 850;
                                    }
                                    else if (propertyName.Equals("炉排3号推料器行程"))
                                    {
                                        tlqXc3.Value = ((int)(data.value)) * 100 / 850;
                                    }
                                    else if (propertyName.Equals("炉排4号推料器行程"))
                                    {
                                        tlqXc4.Value = ((int)(data.value)) * 100 / 850;
                                    }
                                    else if (propertyName.Equals("推料器1号进到位信号"))
                                    {
                                        jdwSignal1.IsOn = data.value > 0;
                                    }
                                    else if (propertyName.Equals("推料器2号进到位信号"))
                                    {
                                        jdwSignal2.IsOn = data.value > 0;
                                    }
                                    else if (propertyName.Equals("推料器3号进到位信号"))
                                    {
                                        jdwSignal3.IsOn = data.value > 0;
                                    }
                                    else if (propertyName.Equals("推料器4号进到位信号"))
                                    {
                                        jdwSignal4.IsOn = data.value > 0;
                                    }
                                    else if (propertyName.Equals("推料器1号退到位信号"))
                                    {
                                        tdwSignal1.IsOn = data.value > 0;
                                    }
                                    else if (propertyName.Equals("推料器2号退到位信号"))
                                    {
                                        tdwSignal2.IsOn = data.value > 0;
                                    }
                                    else if (propertyName.Equals("推料器3号退到位信号"))
                                    {
                                        tdwSignal3.IsOn = data.value > 0;
                                    }
                                    else if (propertyName.Equals("推料器4号退到位信号"))
                                    {
                                        tdwSignal4.IsOn = data.value > 0;
                                    }
                                    else if (propertyName.Equals("炉排1号逆推进到位信号"))
                                    {
                                        ntjdwSignal1.IsOn = data.value > 0;
                                    }
                                    else if (propertyName.Equals("炉排2号逆推进到位信号"))
                                    {
                                        ntjdwSignal2.IsOn = data.value > 0;
                                    }
                                    else if (propertyName.Equals("炉排3号逆推进到位信号"))
                                    {
                                        ntjdwSignal3.IsOn = data.value > 0;
                                    }
                                    else if (propertyName.Equals("炉排4号逆推进到位信号"))
                                    {
                                        ntjdwSignal4.IsOn = data.value > 0;
                                    }
                                    else if (propertyName.Equals("炉排1号逆推退到位信号"))
                                    {
                                        nttdwSignal1.IsOn = data.value > 0;
                                    }
                                    else if (propertyName.Equals("炉排2号逆推退到位信号"))
                                    {
                                        nttdwSignal2.IsOn = data.value > 0;
                                    }
                                    else if (propertyName.Equals("炉排3号逆推退到位信号"))
                                    {
                                        nttdwSignal3.IsOn = data.value > 0;
                                    }
                                    else if (propertyName.Equals("炉排4号逆推退到位信号"))
                                    {
                                        nttdwSignal4.IsOn = data.value > 0;
                                    }
                                    else if (propertyName.Equals("炉排1号顺推进到位信号"))
                                    {
                                        stjdwSignal1.IsOn = data.value > 0;
                                    }
                                    else if (propertyName.Equals("炉排2号顺推进到位信号"))
                                    {
                                        stjdwSignal2.IsOn = data.value > 0;
                                    }
                                    else if (propertyName.Equals("炉排3号顺推进到位信号"))
                                    {
                                        stjdwSignal3.IsOn = data.value > 0;
                                    }
                                    else if (propertyName.Equals("炉排4号顺推进到位信号"))
                                    {
                                        stjdwSignal4.IsOn = data.value > 0;
                                    }
                                    else if (propertyName.Equals("炉排1号顺推退到位信号"))
                                    {
                                        sttdwSignal1.IsOn = data.value > 0;
                                    }
                                    else if (propertyName.Equals("炉排2号顺推退到位信号"))
                                    {
                                        sttdwSignal2.IsOn = data.value > 0;
                                    }
                                    else if (propertyName.Equals("炉排3号顺推退到位信号"))
                                    {
                                        sttdwSignal3.IsOn = data.value > 0;
                                    }
                                    else if (propertyName.Equals("炉排4号顺推退到位信号"))
                                    {
                                        sttdwSignal4.IsOn = data.value > 0;
                                    }
                                    else if (propertyName.Equals("一次风机给定"))
                                    {
                                        lblwind1givehz.Text = (int)data.value + " Hz";
                                    }
                                    else if (propertyName.Equals("一次风机反馈"))
                                    {
                                        lblwind1feedhz.Text = (int)data.value + " rpm";
                                        if (data.value > 0)
                                        {
                                            wind1Control.IsRotating = true;
                                            wind1Control.OutlineColor = Color.LimeGreen;
                                        }
                                        else
                                        {
                                            wind1Control.IsRotating = false;
                                            wind1Control.OutlineColor = Color.Red;
                                        }
                                    }
                                    else if (propertyName.Equals("二次风机给定"))
                                    {
                                        lblwind2givehz.Text = (int)data.value + " Hz";
                                    }
                                    else if (propertyName.Equals("二次风机反馈"))
                                    {
                                        lblwind2feedhz.Text = (int)data.value + " rpm";
                                        if (data.value > 0)
                                        {
                                            wind2Control.IsRotating = true;
                                            wind2Control.OutlineColor = Color.LimeGreen;
                                        }
                                        else
                                        {
                                            wind2Control.IsRotating = false;
                                            wind2Control.OutlineColor = Color.Red;
                                        }
                                    }
                                    else if (propertyName.Equals("第一通道上部负压左"))
                                    {
                                        lblBoilerPressure1.Text = (int)data.value + " Pa";
                                        currentBoilerPressureStatus = currentBoilerPressureStatus && data.value >= incineratorPressureLower && data.value <= incineratorPressureUpper;
                                    }
                                    else if (propertyName.Equals("第一通道上部负压右"))
                                    {
                                        lblBoilerPressure2.Text = (int)data.value + " Pa";
                                        currentBoilerPressureStatus = currentBoilerPressureStatus && data.value >= incineratorPressureLower && data.value <= incineratorPressureUpper;
                                    }
                                    else if (propertyName.Equals("含氧量左"))
                                    {
                                        lblO21.Text = (int)data.value + " %";
                                        currentBoilerOxygenStatus = currentBoilerOxygenStatus && data.value >= incineratorOxygenLower && data.value <= incineratorOxygenUpper;
                                    }
                                    else if (propertyName.Equals("含氧量右"))
                                    {
                                        lblO22.Text = (int)data.value + " %";
                                        currentBoilerOxygenStatus = currentBoilerOxygenStatus && data.value >= incineratorOxygenLower && data.value <= incineratorOxygenUpper;
                                    }
                                    else if (propertyName.Equals("过热器汇汽集箱温度A"))
                                    {
                                        lblJqlx.Text = (int)data.value + " ℃";
                                        currentSteamTempStatus = data.value >= steamTemperatureLower && data.value <= steamTemperatureUpper;
                                    }
                                    else if (propertyName.Equals("炉排1号逆推输出"))
                                    {
                                        if (data.value > 10)
                                        {
                                            ntlpLoading1.StartAnimation();
                                            ntlpLoading1.SetDirection(1);
                                        }
                                        else if(data.value < -10)
                                        {
                                            ntlpLoading1.StartAnimation();
                                            ntlpLoading1.SetDirection(-1);
                                        }
                                        else
                                        {
                                            ntlpLoading1.StopAnimation();
                                        }
                                    }
                                    else if (propertyName.Equals("炉排2号逆推输出"))
                                    {
                                        if (data.value > 10)
                                        {
                                            ntlpLoading2.StartAnimation();
                                            ntlpLoading2.SetDirection(1);
                                        }
                                        else if (data.value < -10)
                                        {
                                            ntlpLoading2.StartAnimation();
                                            ntlpLoading2.SetDirection(-1);
                                        }
                                        else
                                        {
                                            ntlpLoading2.StopAnimation();
                                        }
                                    }
                                    else if (propertyName.Equals("炉排3号逆推输出"))
                                    {
                                        if (data.value > 10)
                                        {
                                            ntlpLoading3.StartAnimation();
                                            ntlpLoading3.SetDirection(1);
                                        }
                                        else if (data.value < -10)
                                        {
                                            ntlpLoading3.StartAnimation();
                                            ntlpLoading3.SetDirection(-1);
                                        }
                                        else
                                        {
                                            ntlpLoading3.StopAnimation();
                                        }
                                    }
                                    else if (propertyName.Equals("炉排4号逆推输出"))
                                    {
                                        if (data.value > 10)
                                        {
                                            ntlpLoading4.StartAnimation();
                                            ntlpLoading4.SetDirection(1);
                                        }
                                        else if (data.value < -10)
                                        {
                                            ntlpLoading4.StartAnimation();
                                            ntlpLoading4.SetDirection(-1);
                                        }
                                        else
                                        {
                                            ntlpLoading4.StopAnimation();
                                        }
                                    }
                                    else if (propertyName.Equals("炉排1号顺推输出"))
                                    {
                                        if (data.value > 10)
                                        {
                                            stlpLoading1.StartAnimation();
                                            stlpLoading1.SetDirection(1);
                                        }
                                        else if (data.value < -10)
                                        {
                                            stlpLoading1.StartAnimation();
                                            stlpLoading1.SetDirection(-1);
                                        }
                                        else
                                        {
                                            stlpLoading1.StopAnimation();
                                        }
                                    }
                                    else if (propertyName.Equals("炉排2号顺推输出"))
                                    {
                                        if (data.value > 10)
                                        {
                                            stlpLoading2.StartAnimation();
                                            stlpLoading2.SetDirection(1);
                                        }
                                        else if (data.value < -10)
                                        {
                                            stlpLoading2.StartAnimation();
                                            stlpLoading2.SetDirection(-1);
                                        }
                                        else
                                        {
                                            stlpLoading2.StopAnimation();
                                        }
                                    }
                                    else if (propertyName.Equals("炉排3号顺推输出"))
                                    {
                                        if (data.value > 10)
                                        {
                                            stlpLoading3.StartAnimation();
                                            stlpLoading3.SetDirection(1);
                                        }
                                        else if (data.value < -10)
                                        {
                                            stlpLoading3.StartAnimation();
                                            stlpLoading3.SetDirection(-1);
                                        }
                                        else
                                        {
                                            stlpLoading3.StopAnimation();
                                        }
                                    }
                                    else if (propertyName.Equals("炉排4号顺推输出"))
                                    {
                                        if (data.value > 10)
                                        {
                                            stlpLoading4.StartAnimation();
                                            stlpLoading4.SetDirection(1);
                                        }
                                        else if (data.value < -10)
                                        {
                                            stlpLoading4.StartAnimation();
                                            stlpLoading4.SetDirection(-1);
                                        }
                                        else
                                        {
                                            stlpLoading4.StopAnimation();
                                        }
                                    }
                                    else if (propertyName.Equals("汽包水位"))
                                    {
                                        lblWaterLevel.Text = (int)data.value + " mm";
                                        waterLevelQb.WaterLevel = (int)data.value; 
                                    }
                                }));
                                break;
                            }
                        }
                        break;
                    }
                }
            }

            //所有炉温都满足条件
            this.Invoke((Action)(() =>
            {
                boilerTempStatus.IsOn = currentBoilerTempStatus;
                steamFlowStatus.IsOn = currentSteamFlowStatus;
                steamTempStatus.IsOn = currentSteamTempStatus;
                boilerOxygenStatus.IsOn = currentBoilerOxygenStatus;
                boilerPressureStatus.IsOn = currentBoilerPressureStatus;
                if (!currentBoilerTempStatus || !currentSteamFlowStatus || !currentSteamTempStatus || !currentBoilerOxygenStatus || !currentBoilerPressureStatus)
                {
                    tsslStatus.Text = "不满足AI运行条件";
                    tsslStatus.ForeColor = Color.Red;
                }
                else
                {
                    //只有此条件才会更改状态，其余提示不更新状态提示
                    if (tsslStatus.Text.Equals("不满足AI运行条件"))
                    {
                        tsslStatus.Text = "正常运行中";
                        tsslStatus.ForeColor = Color.LimeGreen;
                    }
                }
            }));
        }

        //获取预测所需参数
        private async Task GetPredictParams()
        {
            var settings = Properties.Settings.Default;
            int validDataRange = settings.validDataRange;
            int validPeriodRange = settings.validPeriodRange;
            bool currentLpPeriodStatus = true;
            bool currentDataStatus = true;
            string[] paramNames = { "蒸汽流量", "空气预热器出口风温", "空气预热器一级加热出口风温", "一次风机给定", "二次风机给定", "温度上左", "温度上中", "温度上右", "温度中左", "温度中中", "温度中右", "温度下左", "温度下中", "温度下右", "含氧量左", "含氧量右",
                "第一通道上部负压左", "第一通道上部负压右", "炉排第1列1号风室压力", "炉排第1列2号风室压力", "炉排第1列3号风室压力", "炉排第1列4号风室压力", "炉排第2列1号风室压力", "炉排第2列2号风室压力", "炉排第2列3号风室压力", "炉排第2列4号风室压力",
                "炉排第3列1号风室压力", "炉排第3列2号风室压力", "炉排第3列3号风室压力", "炉排第3列4号风室压力", "炉排第4列1号风室压力", "炉排第4列2号风室压力", "炉排第4列3号风室压力", "炉排第4列4号风室压力", "顺推炉排第1列风室压力", "顺推炉排第2列风室压力",
                "顺推炉排第3列风室压力", "顺推炉排第4列风室压力", "逆推炉排下公共风室压力左", "逆推炉排下公共风室压力右", "炉排1号逆推输出", "炉排2号逆推输出", "炉排3号逆推输出", "炉排4号逆推输出", "炉排1号顺推输出", "炉排2号顺推输出", "炉排3号顺推输出", "炉排4号顺推输出",
                "炉排1号推料器输出", "炉排2号推料器输出", "炉排3号推料器输出", "炉排4号推料器输出", "过热器汇汽集箱温度A"};
            string[] periodNames = { "炉排1号逆推进到位信号", "炉排2号逆推进到位信号", "炉排3号逆推进到位信号", "炉排4号逆推进到位信号", "炉排1号顺推进到位信号", "炉排2号顺推进到位信号", "炉排3号顺推进到位信号", "炉排4号顺推进到位信号", "炉排1号推料器行程", "炉排2号推料器行程", "炉排3号推料器行程", "炉排4号推料器行程" };

            //1、获取mongodb中历史数据作为参数值
            List<JSONItem> items = jsonDBHelper.GetItems();
            foreach (JSONItem item in items)
            {
                //从MongoDB获取历史数据
                foreach (string propertyName in paramNames)
                {
                    if (propertyName.Equals(item.name))
                    {
                        // 创建构建器
                        var builder = Builders<OpcItem>.Filter;

                        // 构建排序方式：按 datetime 倒序
                        var sort = Builders<OpcItem>.Sort.Descending(x => x.datetime);

                        FilterDefinition<OpcItem> filter = builder.Eq("tag_name", item.value);
                        List<OpcItem> datalist = mongoDbHelper.findLimit<OpcItem>(colName, filter, sort, 30);
                        if (datalist.Count > 0)
                        {
                            List<double> valueList = new List<double>();
                            foreach (OpcItem data in datalist)
                            {
                                valueList.Add(data.value);
                            }
                            //设置对象的属性值
                            SetPvDataProvertyValue(propertyName, valueList);

                            DateTime nowTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                            DateTime StartTime = Convert.ToDateTime(datalist[datalist.Count - 1].datetime);
                            TimeSpan difference = nowTime - StartTime;
                            double seconds = difference.TotalSeconds;
                            currentDataStatus = currentDataStatus && seconds < validDataRange; //数据有效时间
                            //logger.Info(propertyName + "<===============>" + seconds);
                        }
                        break;
                    }
                }

                //从Sqlite获取周期数据
                foreach (string propertyName in periodNames)
                {
                    if (propertyName.Equals(item.name))
                    {
                        using (var db = new SQLiteService(sqliteName))
                        {
                            // 查询数据
                            var query = "SELECT * FROM Period WHERE TagName = @tagname";
                            var parameters = new Dictionary<string, object> {
                                { "@tagname", item.value }
                            };
                            DataTable result = db.ExecuteQuery(query, parameters);
                            if (result.Rows.Count > 0)
                            {
                                DateTime nowTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                                DateTime StartTime = Convert.ToDateTime(result.Rows[0]["StartTime"].ToString());
                                TimeSpan difference = nowTime - StartTime;
                                double seconds = difference.TotalSeconds;

                                double period = double.Parse(result.Rows[0]["Period"].ToString());
                                //logger.Info(propertyName + "<===========555555555555555555===========>" + currentLpPeriodStatus);
                                if (propertyName.Equals("炉排4号顺推进到位信号"))
                                {
                                    period = 1000;//写固定值
                                    //跳过周期时间有效性验证
                                    currentLpPeriodStatus = currentLpPeriodStatus && true;
                                }
                                else
                                {
                                    currentLpPeriodStatus = currentLpPeriodStatus && seconds < validPeriodRange; //周期有效时间
                                    //logger.Info(propertyName + "<##############>" + seconds);
                                }

                                //logger.Info(propertyName + "<===========6666666666666666===========>" + currentLpPeriodStatus);

                                List<double> valueList = new List<double>();
                                for (int i = 0; i < 30; i++)
                                {
                                    //同样的值复制30份
                                    valueList.Add(period);
                                }
                                //设置对象的属性值
                                string objProperty = "";
                                if (propertyName.Contains("信号"))
                                {
                                    objProperty = propertyName.Replace("信号", "周期");
                                }
                                else {
                                    objProperty = propertyName + "周期";
                                }
                                SetPvDataProvertyValue(objProperty, valueList);

                                //logger.Info(propertyName + "<===========实际运行周期=============>" + period);
                                //更新界面实际运行周期
                                this.Invoke((Action)(() =>
                                {
                                    if (propertyName.Equals("炉排1号逆推进到位信号"))
                                    {
                                        lbl_backward_run1.Text = period + " 秒";
                                    }
                                    else if (propertyName.Equals("炉排2号逆推进到位信号"))
                                    {
                                        lbl_backward_run2.Text = period + " 秒";
                                    }
                                    else if (propertyName.Equals("炉排3号逆推进到位信号"))
                                    {
                                        lbl_backward_run3.Text = period + " 秒";
                                    }
                                    else if (propertyName.Equals("炉排4号逆推进到位信号"))
                                    {
                                        lbl_backward_run4.Text = period + " 秒";
                                    }
                                    else if (propertyName.Equals("炉排1号顺推进到位信号"))
                                    {
                                        lbl_forward_run1.Text = period + " 秒";
                                    }
                                    else if (propertyName.Equals("炉排2号顺推进到位信号"))
                                    {
                                        lbl_forward_run2.Text = period + " 秒";
                                    }
                                    else if (propertyName.Equals("炉排3号顺推进到位信号"))
                                    {
                                        lbl_forward_run3.Text = period + " 秒";
                                    }
                                    else if (propertyName.Equals("炉排4号顺推进到位信号"))
                                    {
                                        lbl_forward_run4.Text = period + " 秒";
                                    }
                                    else if (propertyName.Equals("炉排1号推料器行程"))
                                    {
                                        lblTlqRunVal1.Text = period + " 秒";
                                    }
                                    else if (propertyName.Equals("炉排2号推料器行程"))
                                    {
                                        lblTlqRunVal2.Text = period + " 秒";
                                    }
                                    else if (propertyName.Equals("炉排3号推料器行程"))
                                    {
                                        lblTlqRunVal3.Text = period + " 秒";
                                    }
                                    else if (propertyName.Equals("炉排4号推料器行程"))
                                    {
                                        lblTlqRunVal4.Text = period + " 秒";
                                    }
                                }));
                            }
                            else
                            {
                                logger.Info(propertyName + "<===========99999999999===========>" + currentLpPeriodStatus);
                                currentLpPeriodStatus = false;
                            }
                        }
                        break;
                    }
                }
            }

            //配置文件中设置的上下限范围参数
            double[] steam_flow_SV_range = { (double)Properties.Settings.Default.steamFlowLower, (double)Properties.Settings.Default.steamFlowUpper };
            double[] steam_header_temperature_SV_range = { (double)Properties.Settings.Default.steamTemperatureLower, (double)Properties.Settings.Default.steamTemperatureUpper };
            double[] incinerator_temperature_SV_range = { (double)Properties.Settings.Default.incineratorTemperatureLower, (double)Properties.Settings.Default.incineratorTemperatureUpper };
            double[] incinerator_oxygen_content_SV_range = { (double)Properties.Settings.Default.incineratorOxygenLower, (double)Properties.Settings.Default.incineratorOxygenUpper };
            double[] incinerator_pressure_SV_range = { (double)Properties.Settings.Default.incineratorPressureLower, (double)Properties.Settings.Default.incineratorPressureUpper };
            double[] wind1_range = { (double)Properties.Settings.Default.wind1Lower, (double)Properties.Settings.Default.wind1Upper };
            double[] wind2_range = { (double)Properties.Settings.Default.wind2Lower, (double)Properties.Settings.Default.wind2Upper };
            double[] line1BackwardPeriod_range = { (double)Properties.Settings.Default.line1BackwardPeriodLower, (double)Properties.Settings.Default.line1BackwardPeriodUpper };
            double[] line2BackwardPeriod_range = { (double)Properties.Settings.Default.line2BackwardPeriodLower, (double)Properties.Settings.Default.line2BackwardPeriodUpper };
            double[] line3BackwardPeriod_range = { (double)Properties.Settings.Default.line3BackwardPeriodLower, (double)Properties.Settings.Default.line3BackwardPeriodUpper };
            double[] line4BackwardPeriod_range = { (double)Properties.Settings.Default.line4BackwardPeriodLower, (double)Properties.Settings.Default.line4BackwardPeriodUpper };
            double[] line1ForwardPeriod_range = { (double)Properties.Settings.Default.line1ForwardPeriodLower, (double)Properties.Settings.Default.line1ForwardPeriodUpper };
            double[] line2ForwardPeriod_range = { (double)Properties.Settings.Default.line2ForwardPeriodLower, (double)Properties.Settings.Default.line2ForwardPeriodUpper };
            double[] line3ForwardPeriod_range = { (double)Properties.Settings.Default.line3ForwardPeriodLower, (double)Properties.Settings.Default.line3ForwardPeriodUpper };
            double[] line4ForwardPeriod_range = { (double)Properties.Settings.Default.line4ForwardPeriodLower, (double)Properties.Settings.Default.line4ForwardPeriodUpper };
            
            SetPointObjectProvertyValue("steam_flow", steam_flow_SV_range.ToList());
            SetPointObjectProvertyValue("steam_header_temperature", steam_header_temperature_SV_range.ToList());
            SetPointObjectProvertyValue("incinerator_temperature", incinerator_temperature_SV_range.ToList());
            SetPointObjectProvertyValue("incinerator_oxygen_content", incinerator_oxygen_content_SV_range.ToList());
            SetPointObjectProvertyValue("incinerator_pressure", incinerator_pressure_SV_range.ToList());
            SetPointObjectProvertyValue("wind1", wind1_range.ToList());
            SetPointObjectProvertyValue("wind2", wind2_range.ToList());
            SetPointObjectProvertyValue("grate_line1_backward_period", line1BackwardPeriod_range.ToList());
            SetPointObjectProvertyValue("grate_line2_backward_period", line2BackwardPeriod_range.ToList());
            SetPointObjectProvertyValue("grate_line3_backward_period", line3BackwardPeriod_range.ToList());
            SetPointObjectProvertyValue("grate_line4_backward_period", line4BackwardPeriod_range.ToList());
            SetPointObjectProvertyValue("grate_line1_forward_period", line1ForwardPeriod_range.ToList());
            SetPointObjectProvertyValue("grate_line2_forward_period", line2ForwardPeriod_range.ToList());
            SetPointObjectProvertyValue("grate_line3_forward_period", line3ForwardPeriod_range.ToList());
            SetPointObjectProvertyValue("grate_line4_forward_period", line4ForwardPeriod_range.ToList());


            //所有炉排周期和数据时间都满足条件
            this.Invoke((Action)(() =>
            {
                periodStatus.IsOn = currentLpPeriodStatus;
                dataStatus.IsOn = currentDataStatus;
                if (!currentLpPeriodStatus || !currentDataStatus)
                {
                    tsslStatus.Text = "数据有效时间不满足";
                    tsslStatus.ForeColor = Color.Red;
                }
                else
                {
                    if (tsslStatus.Text.Equals("数据有效时间不满足"))
                    {
                        tsslStatus.Text = "正常运行中";
                        tsslStatus.ForeColor = Color.LimeGreen;
                    }
                }
            }));
        }

        //检测OPC状态
        private async Task checkOpcStatus()
        {
            //1、检测OPC状态
            List<string> opclist = new List<string>();
            string opc500name = ConfigHelper.ReadConfig("Opc500DataCollection");
            string opc800name = ConfigHelper.ReadConfig("Opc800DataCollection");
            opclist.Add(opc500name);
            opclist.Add(opc800name);
            using (var db = new SQLiteService(sqliteName))
            {
                bool currentOpcStatus = true;
                foreach (string opcname in opclist)
                {
                    // 查询数据
                    var query = "SELECT * FROM CheckStatus WHERE Name = @name";
                    var parameters = new Dictionary<string, object> {
                        { "@name", opcname }
                    };
                    DataTable result = db.ExecuteQuery(query, parameters);
                    if (result.Rows.Count > 0)
                    {
                        currentOpcStatus = currentOpcStatus && Convert.ToBoolean(result.Rows[0]["Status"].ToString());
                    }
                }
                this.Invoke((Action)(() =>
                {
                    opcStatus.IsOn = currentOpcStatus;
                    if (!currentOpcStatus)
                    {
                        tsslStatus.Text = "不满足AI运行条件";
                        tsslStatus.ForeColor = Color.Red;
                    }
                }));
            }
        }

        //开始运行
        private void tbStart_Click(object sender, EventArgs e)
        {
            if (!isRunning)
            {
                isRunning = true;
                tbStart.Image = Image.FromFile("Resource/playing.png");
                jsonDBHelper = new JsonDBHelper(jsonconfig);
                dataTimer.Start();
                predictTimer.Start();
                grateLine1BackwardTimer.Start();
                grateLine2BackwardTimer.Start();
                grateLine3BackwardTimer.Start();
                grateLine4BackwardTimer.Start();
                grateLine1ForwardTimer.Start();
                grateLine2ForwardTimer.Start();
                grateLine3ForwardTimer.Start();
                grateLine4ForwardTimer.Start();
                pusher1Timer.Start();
                pusher2Timer.Start();
                pusher3Timer.Start();
                pusher4Timer.Start();

                //模型检测
                Task.Run(async () =>
                {
                    try
                    {
                        await Predit();
                    }
                    catch (Exception ex)
                    { }
                });

                tbStop.Enabled = true;
                ToastMessage.Show(this, "操作成功！", ToastType.Success);
            }
            else
            {
                ToastMessage.Show(this, "程序已经启动！", ToastType.Error);
            }
        }

        //停止运行
        private void tbStop_Click(object sender, EventArgs e)
        {
            if (isRunning)
            {
                isRunning = false;
                tbStop.Enabled = false;
                tbStart.Image = Image.FromFile("Resource/play.png");
                dataTimer.Stop();
                grateLine1BackwardTimer.Stop();
                grateLine2BackwardTimer.Stop();
                grateLine3BackwardTimer.Stop();
                grateLine4BackwardTimer.Stop();
                grateLine1ForwardTimer.Stop();
                grateLine2ForwardTimer.Stop();
                grateLine3ForwardTimer.Stop();
                grateLine4ForwardTimer.Stop();
                pusher1Timer.Stop();
                pusher2Timer.Stop();
                pusher3Timer.Stop();
                pusher4Timer.Stop();
                ToastMessage.Show(this, "停止成功！", ToastType.Success);
            }
            else
            {
                ToastMessage.Show(this, "程序还未运行！", ToastType.Warning);
            }
        }

        //退出程序
        private void tbExit_Click(object sender, EventArgs e)
        {
            DialogResult result = MessageBox.Show("确定要退出程序吗？", "退出确认", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
            if (result == DialogResult.Yes)
            {
                Application.Exit();
            }
        }

        //跳转到设置页面
        private void tbSetting_Click(object sender, EventArgs e)
        {
            using (SettingForm settingsForm = new SettingForm())
            {
                settingsForm.StartPosition = FormStartPosition.CenterScreen;
                if (settingsForm.ShowDialog() == DialogResult.OK)
                {
                    // 设置保存后刷新主窗口
                    LoadSettings();
                }
            }
        }

        //历史曲线页面
        private void history_Click(object sender, EventArgs e)
        {
            // 获取触发事件的控件
            Control clickedControl = sender as Control;
            if (clickedControl != null && dataTimer.Enabled)
            {
                string cnname = clickedControl.AccessibleName;
                List<JSONItem> items = jsonDBHelper.GetItems();
                foreach (JSONItem item in items)
                {
                    if (cnname.Equals(item.name))
                    {
                        using (HistoryChart historyChart = new HistoryChart(cnname, item.value, item.messure))
                        {
                            historyChart.StartPosition = FormStartPosition.CenterScreen;
                            if (historyChart.ShowDialog() == DialogResult.OK)
                            {

                            }
                        }
                        break;
                    }
                }
            }
        }

        //OPC 读写
        private void tbTest_Click(object sender, EventArgs e)
        {
            using (OpcWrite opcForm = new OpcWrite())
            {
                opcForm.StartPosition = FormStartPosition.CenterScreen;
                if (opcForm.ShowDialog() == DialogResult.OK)
                {
                    
                }
            }
        }
    }
}
